#include "GraphicsDevice.h"
#include "Texture.h"
#include "IShaderProgram.h"
#include "IResourceManager.h"
//#include "TextureAtlas.h"
#include "Color.h"
#include "IContext.h"

NS_B2D_BEGIN

GraphicsDevice::GraphicsDevice(void)
	: mActiveRenderTarget(nullptr)

	, mActiveShaderProgram(nullptr)

	, mBlendSrcCoeff(BlendCoefficient::SRC_ALPHA)
	, mBlendDstCoeff(BlendCoefficient::ONE_MINUS_SRC_ALPHA)
	, mBlendFunction(BlendFunction::FUNC_ADD)
{
	memset(mTextureSlots, 0, sizeof(mTextureSlots));
	
	IResourceManager& rm = *GetContext().getInstance<IResourceManager>();
	//rm.registerHandler( *(new TextureAtlasHandler()) );
}

GraphicsDevice::~GraphicsDevice(void)
{/*
	// Release textures
	// Note: can not call clearTextures() because this calls assignTextureSlot()
	// which is virtual and thus not available at this point
	for( size_t i = 0; i < TextureUnit::MAX; ++i )
	{
		if( mTextureSlots[i] != nullptr )
			mTextureSlots[i]->drop();
	}
	// Release active shader
	if( mActiveShaderProgram != nullptr )
		mActiveShaderProgram->drop();*/
	// NOTE - resource manager will destroy these resources
}


void GraphicsDevice::_setActiveRenderTarget(const RenderTarget& rt)
{
	mActiveRenderTarget = const_cast<RenderTarget*>(&rt);
}

void GraphicsDevice::setActiveShaderProgram(const ShaderProgramPtr& sp)
{
	if( mActiveShaderProgram != sp )
	{
		mActiveShaderProgram = sp;
		setActiveShaderProgramImpl();
	}
}

size_t GraphicsDevice::getActiveTextureCount(void) const
{
	size_t count = 0;
	for(size_t i = 0; i < TextureUnit::MAX; ++i)
	{
		if( mTextureSlots[i] != nullptr )
			++count;
	}
	return count;
}

TexturePtr GraphicsDevice::getTextureAt(TextureUnit::Unit slot) const
{
	return mTextureSlots[slot];
}

void GraphicsDevice::clearTextures(void)
{
	// Set null texture for each index
	for( size_t i = 0; i < TextureUnit::MAX; ++i )
	{
		setTextureSlot(static_cast<TextureUnit::Unit>(i), nullptr);
	}
}

void GraphicsDevice::setBlending(BlendCoefficient src, BlendCoefficient dst, BlendFunction function)
{
	mBlendSrcCoeff = src;
	mBlendDstCoeff = dst;
	mBlendFunction = function;
	setBlendingImpl();
}

void GraphicsDevice::getBlending(BlendCoefficient& src, BlendCoefficient& dst, BlendFunction& function) const
{
	src = mBlendSrcCoeff;
	dst = mBlendDstCoeff;
	function = mBlendFunction;
}

NS_B2D_END